open tigerlex
open tigergrm
open tigerescap
open tigerseman
open BasicIO Nonstdio

(* toma un flujo de entrada y devuelve un lexbuf *)
(* lexstream : instream -> lexbuf *)
fun lexstream (is : instream) =
	Lexing.createLexer (fn b => fn n => buff_input is b 0 n);

(* toma un lexbuf, imprime un error y levanta una excepción *)
fun errParsing (lbuf : Lexing.lexbuf) = 
	(print("Error en parsing!("
	^(makestring(!num_linea))^
	")["^(Lexing.getLexeme lbuf)^"]\n"); raise Fail "fin!")

(* toma los argumentos de línea de comandos y ejecuta *)
fun main (args : string list) =
	let	
		(* toma una lista de strings l y un string s y devuelve un par
		de un bool indicando si s está en l y el resto de la lista
		sin ocurrencias de s *)
		fun arg (l, s) =
			(List.exists (fn x => x=s) l, List.filter (fn x => x<>s) l)

		val (arbol, l1)		= arg(args, "-arbol")
		val (escapes, l2)	= arg(l1, "-escapes")
		val (trans, l3)     = arg(l2, "-trans")
(*		val (ir, l3)		= arg(l2, "-ir") 
		val (canon, l4)		= arg(l3, "-canon") 
		val (code, l5)		= arg(l4, "-code") 
		val (flow, l6)		= arg(l5, "-flow") 
		val (inter, l7)		= arg(l6, "-inter")
*)
		val (entrada : instream) =
			case l3 of
			[n] => ((open_in n)
					handle _ => raise Fail ("Archivo "^n^" no existe"))
			| [] => std_in
			| s => raise Fail ("Opción desconocida: "^concat s)

		val lexbuf = lexstream entrada

	(* ejecuta el parser, devuelve el AST del programa (tigergrm, tigerlex) *)
		val expr = prog Tok lexbuf handle _ => errParsing lexbuf
	(* con la opción -escapes se detectan las variblas escapadas (tigerescap) *)
		val _ = if escapes then findEscape(expr) else ()
	(* con la opción -arbol imprime el AST (tigerpp) *)
		val _ = if arbol then tigerpp.exprAst expr else ()
	in
	(* con la opción -trans se verifican tipos (tigerseman) *)
		if trans then transProg(expr) else ();
		print "yes!!\n"
	end	handle Fail s => print("Fail: "^s^"\n")

val _ = main (CommandLine.arguments ())
